#ifndef PINYINHANDLER_H
#define PINYINHANDLER_H

#include "dicthandler.h"
#include "BaiduPinyinApi.h" 
#include "OpenCCUtil.h"     

#include <QObject>
#include <QString>
#include <QVector>
#include <QMap>
#include <QSet>
#include <QThread>
#include <QMutex>

enum PinyinType {
	FullPinyin,    // 全拼
    DoublePinyin,  // 双拼
    SimplePinyin   // 简拼
};

// 候选词结构
struct PinyinCandidate {
	QString text;		
	int frequency;		// 词频 sort
	QString pinyin;
	bool isUserWord;	// 用户自定词

	// sort
	bool operator<(const PinyinCandidate& other) const {
		return frequency > other.frequency;		// 高词频在前面
	}

	// 文本相同 同一候选词
	bool operator==(const PinyinCandidate& other) const {
		return text == other.text;
	}
};

// 前置声明：解决友元类编译依赖
class PinyinWorker;

class PinyinHandler : public QObject
{
	Q_OBJECT
	// 声明友元类：允许 PinyinWorker 访问所有成员（包括 private）
    friend class PinyinWorker; 
public:
	explicit PinyinHandler(QObject *parent = nullptr);
    ~PinyinHandler() override;

	// funcs
	////////////////////////////////  拼音类型与模糊音配置 /////////////////////////////////////
	void setPinyinType(PinyinType type);
	void setFuzzyPinyinEnabled(bool enabled);		// 模糊音启用
	void setFuzzyPinyinMap(const QMap<QString, QStringList>& fuzzyMap);
	////////////////////////////////  拼音输入处理 /////////////////////////////////////
	void processInput(const QString& input);
	void reset();
	QString currentPinyin() const;
	bool isProcessing() const;

	// ------ load json -------
	bool loadBaseDictFromConfig();			// 从 ConfigManager 读取配置并加载 JSON 词库（对外主要接口）
	QMap<QString, QVector<PinyinCandidate>> getSystemPinyinMap() const { return m_pinyinMap; }		// 获取系统词库缓存（供 DictHandler 调用，无需加锁，因加载后只读）

	// 双拼优化
	QString getDoublePinyinScheme() const { return m_doublePinyinScheme; }

	// 拓展的汉字转拼音 汉字转拼音
	QString getDefaultPinyinForChar(const QChar& ch);
    QString convertTextToPinyin(const QString& text);

	// 联动接口
	void setConvertDirection(OpenCCUtil::ConvertDirection dir); // 设置简繁转换方向
    void setUseBaiduApi(bool use); // 开关：是否使用百度API获取多音字拼音

signals:
	void candidatesGenerated(const QVector<PinyinCandidate>& candidates);		// 候选词生成完成
	void inputIncomplete(const QString& currentPinyin);							// 拼音输入不完整（需要更多输入）
	void invalidInput(const QString& invalidText);								// 拼音输入无效
	void processFinished(const QVector<PinyinCandidate>& candidates);			// 处理完成（供内部线程使用）

	// 通知系统词库加载结果（true=成功，false=失败）
    void baseDictLoaded(bool success);

private slots:
	// get Thread ans
	void onProcessFinished(const QVector<PinyinCandidate>& candidates);
	void onBaiduConversionSuccess(const QString& text, const QString& pinyin);	// baidu API的backtrack

private:
	// funcs
	QVector<PinyinCandidate> internalProcess(const QString& input);				// 内部处理函数（在子线程中执行）
    QVector<PinyinCandidate> parseFullPinyin(const QString& pinyin);			// 全拼解析
    QVector<PinyinCandidate> parseDoublePinyin(const QString& pinyin);			// 双拼解析	加锁
    QVector<PinyinCandidate> parseSimplePinyin(const QString& pinyin);			// 简拼解析
    QStringList applyFuzzyPinyin(const QString& pinyin);						// 应用模糊音转换
    void initPinyinMap();														// 初始化拼音映射表
    void initDoublePinyinMap();													// 初始化双拼映射表

	// tool func
	QStringList splitPinyinSyllables(const QString& pinyin);  // 分割多音节拼音（如"nihao"→["ni","hao"]）
    bool isPrefixOfAnyPinyin(const QString& prefix);          // 判断是否为某个拼音的前缀（用于不完整输入）

	// json tool
	bool loadBaseDictFromJSON(const QString& jsonPath, bool encrypted);			// 内部 JSON 词库加载（支持加密）
    void loadDefaultBaseDict();												  	// 兜底：加载内置默认小词库（防止主词库加载失败导致程序无候选词）
    void initCharToPinyinMap();													// 构建汉字→拼音反向映射（后续简繁体/文本转拼音可用，可选实现）

	// union helper
	QVector<PinyinCandidate> convertCandidatesSimplifiedTraditional(const QVector<PinyinCandidate>& candidates); // 转换候选词简繁
    QString getPolyphonicPinyinFromBaidu(const QString& word); // 从百度API获取多音字拼音

private:
	// 组件及成员变量
	PinyinType m_pinyinType;               // 当前拼音类型
    bool m_fuzzyEnabled;                   // 是否启用模糊音
    QMap<QString, QStringList> m_fuzzyMap; // 模糊音映射表  （如"z"→["zh"]）
    QString m_currentPinyin;               // 当前拼音串
    bool m_isProcessing;                   // 是否正在处理

    QMap<QString, QVector<PinyinCandidate>> m_pinyinMap;	// 拼音到汉字的映射表
    QMap<QChar, QString> m_doublePinyinMap;					// 双拼映射表
	QSet<QString> m_allSyllables;                         // 所有单音节集合（用于快速校验）

    QThread* m_workerThread;							    // 处理线程

	QString m_doublePinyinScheme; 							// 当前双拼方案（如"Sogou"） 增加微软方案

    QMutex m_processMutex;       							// 保护 m_isProcessing 线程安全
	QMutex m_doublePinyinMutex; 							// 保护 m_doublePinyinMap 的线程安全
	//////////////////////////////////////////////
	QMap<QChar, QStringList> m_charToPinyinMap; // 汉字→多拼音映射（如“行”→["xing","hang"]）
	//////////////////////////////////////////////

	// API | OpenCC member
	OpenCCUtil* m_openccUtil = nullptr; // 简繁转换工具
    OpenCCUtil::ConvertDirection m_convertDir = OpenCCUtil::ConvertDirection::T2S; // 默认简体
    BaiduPinyinApi* m_baiduApi = nullptr; // 百度API工具
    bool m_useBaiduApi = true; // 是否使用百度API（默认开启）
    QMap<QString, QString> m_polyphonicCache; // 多音字拼音缓存（词语→拼音）
    QMutex m_polyphonicCacheMutex; // 多音字缓存互斥锁

};


#endif	// PINYINHANDLER_H